/*
 * @Author: zzy 917106840648 NJUST
 * @Date: 2020-03-1 08:55:51
 * @LastEditTime: 2020-04-06 18:04:29
 * @LastEditors: Please set LastEditors
 * @Description: In User Settings Edit
 * @FilePath: \W+compiler\LexicalAnalyzer.cpp
 */
#include "..\include\LexicalAnalyzer.h"

const char* SOURCE        = "SOURCE_S.txt";
const char* TOKEN         = "TOKEN_S.txt";
const char* LexicalOutput = "LexicalOutput_S.txt";
// const char* SOURCE        = "SOURCE.txt";
// const char* TOKEN         = "TOKEN.txt";
// const char* LexicalOutput = "LexicalOutput.txt";

const char* LexicalInput = "LexicalInput.txt";

Nfa::Nfa() : _stateNum(0), _out(std::cout) {}

void Nfa::toNfa()
{
    int  N;
    bool first = true;  //判断是否为第一个

    _in.open(LexicalInput);
    char unFinal;   //读入第一个非终结符
    char non;       //读入无用字符
    char next[10];  //读入->后 字符串
    _in >> N;

    // cout << "N : " << N << endl;

    //设置 终态
    _data.Z.stateName = 'Z';

    while (N--) {
        _in >> unFinal >> non >> non >> next;

        // cout << unFinal << "  " << next << endl;
        if (first) {
            //初始状态
            _data.S.stateName = unFinal;
            first             = false;
        }

        if (strlen(next) > 1) {
            //添加边
            edge e;
            e.edgeStart  = state(unFinal);
            e.edgeEnd    = state(next[1]);
            e.edgeSymbol = next[0];
            _data.f.push_back(e);
        }
        else {
            //使用 # 表示空
            edge e;
            e.edgeStart = state(unFinal);
            e.edgeEnd   = _data.Z;

            if (next[0] == '#') {
                e.edgeSymbol = '#';
            }
            else {
                e.edgeSymbol = next[0];
            }

            _data.f.push_back(e);
        }
    }
}

void Nfa::show() const
{
    _out << "NFA 的起始状态：" << _data.S.stateName << endl;
    _out << "NFA 的结束状态：" << _data.Z.stateName << endl << endl;
    _out << "NFA 的symbolSet : ";

    set<char>::iterator it = _data.symbolSet.begin();
    while (it != _data.symbolSet.end()) {
        _out << (*it);
        ++it;
    }
    _out << endl;

    for (auto it : _data.f) {
        _out << "from state:  " << it.edgeStart.stateName
             << "\t    to state: " << it.edgeEnd.stateName << "\t\tby  ";
        if (it.edgeSymbol == '#')
            _out << R"+(ε)+" << endl;
        else
            _out << it.edgeSymbol << endl;
    }
    _out << endl;
}

/**
 * @description: 更新有穷集 有穷字母集
 * @param {type}
 * @return:
 */
void Nfa::update()
{
    for (auto it : _data.f) {
        _data.stateSet.insert(it.edgeStart);
        _data.stateSet.insert(it.edgeEnd);
        _data.symbolSet.insert(it.edgeSymbol);
    }
}

void Nfa::run()
{
    toNfa();

    update();

    show();
}

Dfa::Dfa() : _out(std::cout) {}

void Dfa::show() const
{
    _out << "DFA 的起始状态：" << _data.S.stateName << endl;
    _out << "DFA 的结束状态：";
    set<state>::iterator iter = _data.Z.begin();
    while (iter != _data.Z.end()) {
        _out << (*iter).stateName << ' ';
        ++iter;
    }
    _out << endl;
    _out << "DFA 的所有状态：";
    set<state>::iterator iter2 = _data.stateSet.begin();
    while (iter2 != _data.stateSet.end()) {
        _out << (*iter2).stateName << ' ';
        ++iter2;
    }
    _out << endl;

    for (auto it : _data.f) {
        _out << "from state:  " << it.edgeStart.stateName
             << "\t    to state: " << it.edgeEnd.stateName << "\t\tby  ";
        if (it.edgeSymbol == '#')
            _out << R"+(ε)+" << endl;
        else
            _out << it.edgeSymbol << endl;
    }
    _out << endl;
}

/**
 * @description: 更新有穷集 有穷字母集
 * @param {type}
 * @return:
 */
void Dfa::update()
{
    for (auto it : _data.f) {
        _data.stateSet.insert(it.edgeStart);
        _data.stateSet.insert(it.edgeEnd);
        _data.symbolSet.insert(it.edgeSymbol);
    }
}

/**
 * @description: 判断该状态是否为 DFA
 * @param {type}
 * @return:
 */
bool Dfa::isFinal(state temp)
{
    set<state>::iterator it = _data.Z.begin();
    for (; it != _data.Z.end(); it++) {
        if (temp.stateName == (*it).stateName) {
            return true;
        }
    }
    return false;
}

/**
 * @description: 判断 str 是否符合 DFA
 * @param {type}
 * @return:
 */
bool Dfa::isDfa(string str)
{
    int   i          = 0;
    state startState = _data.S;
    int   length     = str.length();

    // cout << "isDfa()----begin : " << endl;

    vector<edge>::iterator it = _data.f.begin();

    for (i = 0; i < length; i++) {
        for (it = _data.f.begin(); it != _data.f.end(); it++) {
            if ((*it).edgeStart.stateName == startState.stateName &&
                (*it).edgeSymbol == str[i]) {
                // cout << (*it).edgeStart.stateName << "->"
                //      << (*it).edgeEnd.stateName << " by " << (*it).edgeSymbol
                //      << endl;
                startState = (*it).edgeEnd;
                if (isFinal((*it).edgeEnd) && i == length - 1) {
                    // cout << "isDfa()----end True" << endl;
                    return true;
                }
                break;
            }
        }
    }
    // cout << "isDfa()----end False" << endl;
    return false;
}

void Dfa::run()
{
    update();

    show();
}

/**
 * @description: 去除string中重复的字符
 * @param {type}
 * @return:
 */
string removeDuplicate(string s)
{
    int len = s.length();
    if (len < 2)
        return s;
    string str = "";
    for (int i = 0; i < len; ++i) {
        if (s[i] != ' ') {
            str += s[i];
            for (int j = i + 1; j < len; ++j) {
                if (s[j] == s[i]) {
                    s[j] = ' ';
                }
            }
        }
    }
    return str;
}

/**
 * @description: 求 e 闭包运算   使用'ABC'表示 ABC三个状态的集合
 * @param state t 代表 状态 -> 起始状态 或 processState的newState
 *        Nfa nfa 为当前操作的 NFA
 * @return:
 */
state eclosure(state t, Nfa& nfa)
{
    state closure = state(t);
    // cout << "eclosure()----begin" << endl;
    // cout << "eclosure()----Input :  " << t.stateName << endl;
    Nfaunit nfaunit = nfa.getNfa();

    //对stateName集合进行遍历
    string::iterator iter = t.stateName.begin();
    for (; iter != t.stateName.end(); iter++) {
        char         stateSingle = *iter;
        string       statetemp;
        stringstream sstream;
        sstream << stateSingle;
        statetemp = sstream.str();

        // cout << " 状态分割 : " << stateSingle << endl;
        for (std::vector<edge>::iterator it = nfaunit.f.begin();
             it != nfaunit.f.end(); it++) {
            if ((*it).edgeStart.stateName == statetemp &&
                (*it).edgeSymbol == '#') {
                closure.stateName += (*it).edgeEnd.stateName;
                //匹配成功
                // cout << (*it).edgeStart.stateName << "->"
                //      << (*it).edgeEnd.stateName << " by #" << endl;
            }
        }
    }
    //重复 状态去除
    closure.stateName = removeDuplicate(closure.stateName);
    // cout << "eclosure()----end" << endl;
    // cout << "eclosure()---output : " << closure.stateName << endl;
    return closure;
}

/**
 * @description: 求得 T 通过 symbol 可以到达的 状态
 * @param state t 代表 第一次 eclosure后的状态集合 此时为 "集合"!
 * @return:
 */
state moveI(state t, Nfa& nfa, char symbol)
{
    state moveInput  = state(t);
    state moveOutput = state();
    // cout << "move()----begin " << symbol << endl;
    // cout << "move()----Input : " << moveInput.stateName << endl;
    Nfaunit nfaunit = nfa.getNfa();

    //对stateName集合进行遍历
    string::iterator iter = moveInput.stateName.begin();
    for (; iter != moveInput.stateName.end(); iter++) {
        char         stateSingle = *iter;
        string       statetemp;
        stringstream sstream;
        sstream << stateSingle;
        statetemp = sstream.str();

        // cout << " 状态分割 : " << stateSingle << endl;
        for (std::vector<edge>::iterator it = nfaunit.f.begin();
             it != nfaunit.f.end(); it++) {
            if ((*it).edgeStart.stateName == statetemp &&
                (*it).edgeSymbol == symbol) {
                moveOutput.stateName += (*it).edgeEnd.stateName;
                //匹配成功
                // cout << (*it).edgeStart.stateName << "->"
                //      << (*it).edgeEnd.stateName << " by " << symbol << endl;
            }
        }
    }

    //重复 状态去除
    moveOutput.stateName = removeDuplicate(moveOutput.stateName);
    // cout << "move()----end" << endl;
    // cout << "move()----Output : " << moveOutput.stateName << endl;
    return moveOutput;
}

/**
 * @description:实现NFA to DFA 的转换
 * @param {type}
 * @return:
 */
void NFA2DFA(Nfa& nfa, Dfa& dfa)
{
    Nfaunit nfaunit = nfa.getNfa();
    //初始状态
    state startState = nfaunit.S;
    state t0         = state();
    state t1         = state();
    state t0_new     = state();
    state t1_new     = state();

    //对processState的oldState进行判断是否存在终态
    string::size_type idx;

    //对以确定的 state进行计数   控制新的状态重命名 以及 确定状态的数量
    int          stateNum     = 0;
    int          existNum     = 0;
    bool         isExist      = false;
    bool         isEnd        = false;
    char         charStateNum = char(stateNum + 'A');
    string       statetemp;
    stringstream sstream;
    sstream << charStateNum;
    statetemp = sstream.str();
    sstream.str("");

    // cout << "NFA2DFA()----begin" << endl;
    //设置DFA的初始状态
    dfa._data.S.stateName = statetemp;

    //初始化结构体数组
    processState ps[100];
    for (int i = 0; i < 100; i++) {
        ps[i].oldState     = state();
        ps[i].newState     = state();
        ps[i].isGetClosure = false;
        ps[i].isFinal      = false;
    }

    //循环开始
    //第一次 s 初始化 eclosure
    t0 = eclosure(startState, nfa);

    ps[stateNum].oldState     = t0;
    ps[stateNum].newState     = statetemp;
    ps[stateNum].isGetClosure = true;

    t0_new.stateName = statetemp;

    //开始新状态为 t0
    startState = t0;

    // cout << "添加新的状态：" << endl;
    // cout << "oldState : " << t0.stateName << endl;
    // cout << "newState : " << statetemp << endl;
    // cout << "isGetClosure : true" << endl;

    //判断是否为终态，若为终态，则在DFA中添加终态
    idx = ps[stateNum].oldState.stateName.find('Z');
    if (idx == string::npos) {
        //不存在终态
        ps[stateNum].isFinal = false;
    }
    else {
        ps[stateNum].isFinal = true;
        dfa._data.Z.insert(statetemp);
        // cout << "dfa添加终态 : " << statetemp << endl;
    }

    //得到新的状态
    stateNum++;
    charStateNum = char(stateNum + 'A');
    sstream << charStateNum;
    statetemp = sstream.str();
    sstream.str("");
    // cout << "第" << stateNum - 1 << "次新状态 : " << statetemp << endl;

    isExist = false;

    while (startState.stateName != "-1") {
        isExist = false;
        // cout << "新状态为" << startState.stateName << endl;
        //对每一个 非终结符 进行 单独的 move()运算 和第二次的 closure()
        for (std::set<char>::iterator it = nfaunit.symbolSet.begin();
             it != nfaunit.symbolSet.end(); it++) {
            if ((*it) != '#') {
                // cout << "第二次closure-------begin" << endl;
                t1 = eclosure(moveI(startState, nfa, (*it)), nfa);
                // cout << "第二次closure-- " << (*it) << " --end" << endl;

                if (t1.stateName == "") {
                    // cout << "t1 为空 跳过" << endl;
                    continue;
                }

                isExist = false;
                //遍历 processState中是否有重复的原状态
                for (existNum = 0; existNum < stateNum; existNum++) {
                    if (ps[existNum].oldState.stateName == t1.stateName) {
                        isExist = true;
                        break;
                    }
                }
                if (!isExist) {
                    //不重复
                    ps[stateNum].oldState           = t1;
                    ps[stateNum].newState.stateName = statetemp;
                    ps[stateNum].isGetClosure       = false;
                    t1_new.stateName                = statetemp;

                    // cout << "添加新的状态：" << endl;
                    // cout << "               oldState : " << t1.stateName
                    //      << endl;
                    // cout << "               newState : " << statetemp <<
                    // endl; cout << "               isGetClosure : false" <<
                    // endl;

                    //判断是否为终态，若为终态，则在DFA中添加终态
                    idx = ps[stateNum].oldState.stateName.find('Z');
                    if (idx == string::npos) {
                        //不存在终态
                        ps[stateNum].isFinal = false;
                        // cout << "非终态-" << endl;
                    }
                    else {
                        ps[stateNum].isFinal = true;
                        dfa._data.Z.insert(statetemp);
                        // cout << "DFA添加终态 : " << statetemp << endl;
                    }
                    //得到新的状态
                    stateNum++;
                    charStateNum = char(stateNum + 'A');
                    sstream << charStateNum;
                    statetemp = sstream.str();
                    sstream.str("");
                    // cout << "第" << stateNum << "次新状态 : " << statetemp
                    //     << endl;

                    //将状态添加到DFA中
                    edge e;
                    e.edgeStart  = t0_new;
                    e.edgeEnd    = t1_new;
                    e.edgeSymbol = *it;
                    dfa._data.f.push_back(e);
                    // cout << "DFA添加 f : ";
                    // cout << t0_new.stateName << "->" << t1_new.stateName
                    //      << " by " << *it << endl;

                    isExist = false;
                }
                else {
                    t1_new.stateName = ps[existNum].newState.stateName;
                    // cout << "第二次elosure 存在状态重复 ----" << t1.stateName
                    //      << endl;

                    //将状态添加到DFA中
                    edge e;
                    e.edgeStart  = t0_new;
                    e.edgeEnd    = t1_new;
                    e.edgeSymbol = *it;
                    dfa._data.f.push_back(e);
                    // cout << "DFA添加 f : " << endl;
                    // cout << t0_new.stateName << "->" << t1_new.stateName
                    //      << " by " << *it << endl;
                    isExist = false;
                }
            }
        }
        // cout << endl;

        int i;
        for (i = 0; i < stateNum; i++) {
            if (ps[i].isGetClosure == false) {
                startState         = ps[i].oldState;
                isEnd              = false;
                ps[i].isGetClosure = true;
                t0_new             = ps[i].newState;
                // cout << "存在未遍历集合 : " << startState.stateName << endl
                //      << endl;
                break;
            }
        }

        // cout << endl << "输出所有processState状态 : " << endl;
        //输出所有 processState的状态
        // for (i = 0; i < stateNum; i++) {
        //     cout << "i : " << i << endl;
        //     cout << ps[i].oldState.stateName << endl;
        //     cout << ps[i].newState.stateName << endl;
        //     cout << ps[i].isGetClosure << endl;
        //     cout << endl;
        // }
        // cout << endl;

        //未重复
        if (isEnd == true) {
            startState.stateName = "-1";
        }
        isEnd = true;
    }
}

/**
 * 此处开始进行 词法分析器 分析部分
 * 对五类 token 进行识别 包括：关键词，标识符，常量，限定符，运算符
 *
 * 关键词 key：0--16
 * return for while break continue if else default
 *    r     f   w    b     c      i    e     d
 *
 * unsigned long int float double char bool void string
 *    u       g   t    o      d      a   l     v    s
 *
 * 标识符 identifier 变量 : ---> 18  z
 * 由字母+数组或_+数字/字母
 * 用来表示各种名字，如变量名，数组名，过程名等等。
 *
 * 常量 const: ---->19  y
 * 最好能区分类型 doublw float int 科学计数法 复数 bool ""字符串型
 * 符号数、小数、科学计数法、复数(数字+数字i)
 *
 * 限定符 : 界符--->20
 * () {} [] , ;
 *
 * 运算符：
 * 单目运算符 : ---->21
 *              + - * / ! % ~ & | ^ =
 * 双目运算符 : ---->22
 *             ++ -- || <= >= != == += -= /= *=
 *
 * 注释 ：---->23
 * 识别 # 为注释直接省略 可直接放在关键词中
 */
ofstream outputTOKEN;
ofstream outputLexicalOutput;
FILE*    file_input        = NULL;
int      keywordNum        = 17;
int      singleoperatorNum = 13;
int      doubleoperatorNum = 12;
int      delimiterNum      = 9;

//关键词
const char keyword[KEYWORDMAX][12] = {
    "return", "for",     "while",    "break", "continue", "if",
    "else",   "default", "unsigned", "long",  "int",      "float",
    "double", "char",    "bool",     "void",  "string"};
//单目运算符
const char singleOperator[20] = {'+', '-', '*', '/', '!', '%', '~',
                                 '&', '|', '^', '=', '>', '<'};
//双目运算符
const char doubleOpertor[15][5] = {
    "++", "--", "||", "<=", "!=", "==", ">=", "+=", "-=", "*=", "/=", "&&"};

//界符
const char delimiter[20] = {',', '(', ')', '{', '}', ';'};  //界符

//判断是否为keyword
/**
 * @description: 转换keyword 输出token时使用
 * @param {type}
 * @return: 0-16为正确 -1为错误
 */
int toKeyword(char str[])
{
    if (strcmp(str, keyword[0]) == 0) {  // return 0
        return 0;
    }
    if (strcmp(str, keyword[1]) == 0) {  // for 1
        return 1;
    }
    if (strcmp(str, keyword[2]) == 0) {  // while 2
        return 2;
    }
    if (strcmp(str, keyword[3]) == 0) {  // break 3
        return 3;
    }
    if (strcmp(str, keyword[4]) == 0) {  // continue 4
        return 4;
    }
    if (strcmp(str, keyword[5]) == 0) {  // if 5
        return 5;
    }
    if (strcmp(str, keyword[6]) == 0) {  // else 6
        return 6;
    }
    if (strcmp(str, keyword[7]) == 0) {  // default 7
        return 7;
    }
    if (strcmp(str, keyword[8]) == 0) {  // unsigned 8
        return 8;
    }
    if (strcmp(str, keyword[9]) == 0) {  // long 9
        return 9;
    }
    if (strcmp(str, keyword[10]) == 0) {  // int 10
        return 10;
    }
    if (strcmp(str, keyword[11]) == 0) {  // float 11
        return 11;
    }
    if (strcmp(str, keyword[12]) == 0) {  // double 12
        return 12;
    }
    if (strcmp(str, keyword[13]) == 0) {  // char 13
        return 13;
    }
    if (strcmp(str, keyword[14]) == 0) {  // bool 14
        return 14;
    }
    if (strcmp(str, keyword[15]) == 0) {  // void 15
        return 15;
    }
    if (strcmp(str, keyword[16]) == 0) {  // string 16
        return 16;
    }
    return -1;
}

/**
 * @description: 判断是否为整数
 * @param {type}
 * @return:
 */
bool isInteger(char a)
{
    if (a >= '0' && a <= '9')
        return true;
    return false;
}

/**
 * @description: 判断是否为字母 大小写字母
 * @param {type}
 * @return:
 */
bool isLetter(char a)
{
    if (a >= 'a' && a <= 'z') {
        return true;
    }
    if (a >= 'A' && a <= 'Z') {
        return true;
    }
    return false;
}

/**
 * @description: 判断是否为 keyword
 * @param {type}
 * @return:
 */
bool isKeyword(const char a[])
{
    for (int i = 0; i < keywordNum; i++) {
        if (strcmp(keyword[i], a) == 0) {
            return true;
        }
    }
    return false;
}

/**
 * @description: 判断是否为 单目运算符
 * @param {type}
 * @return:
 */
bool isSingleOperator(char a)
{
    for (int i = 0; i < singleoperatorNum; ++i) {
        if (singleOperator[i] == a)
            return true;
    }
    return false;
}

/**
 * @description: 判断是否为 双目运算符
 * @param {type}
 * @return:
 */
bool isDoubleOperator(char a[])
{
    for (int i = 0; i < doubleoperatorNum; ++i) {
        if (strcmp(doubleOpertor[i], a) == 0)
            return true;
    }
    return false;
}

/**
 * @description: 判断是否为界符
 * @param {type}
 * @return:
 */
bool isDelimiter(char a)
{
    for (int i = 0; i < delimiterNum; i++) {
        if (a == delimiter[i]) {
            return true;
        }
    }
    return false;
}

/**
 * @description: 对输入的 源代码进行 分析
 * @param {type}
 * @return:
 */
void analyze(Dfa& dfa)
{
    int  i             = 0;
    int  line          = 1;
    int  type          = 0;
    int  inputNum      = 0;
    bool analyzeFinish = false;

    char input;
    char analyzeString[100];

    input = fgetc(file_input);
    while (!analyzeFinish) {
        type     = -1;
        inputNum = 0;

        //识别 # 开头的注释
        if (input == '#') {
            // skip macro, because we will not support it
            while ((input = fgetc(file_input)) != '\n') {}
        }

        //识别常量 整数 小数 科学计数法 复数
        if (isInteger(input)) {
            type                      = 1;
            analyzeString[inputNum++] = input;
            input                     = fgetc(file_input);

            while (input == 'e' || isInteger(input) || input == '.' ||
                   input == '+' || input == 'i' || input == '-') {
                analyzeString[inputNum++] = input;
                input                     = fgetc(file_input);
            }
            analyzeString[inputNum++] = '\0';
            inputNum                  = 0;
        }
        //对type为1 进行处理
        if (type == 1) {
            //使用 dfa 对 常量做识别
            string temp = analyzeString;
            if (dfa.isDfa(temp)) {
                // cout << "<" << line << ",19," << analyzeString << ">" <<
                // endl;
                outputTOKEN << "<" << setw(2) << setfill('0') << line << ",19,"
                            << analyzeString << ">" << endl;
                outputLexicalOutput << "y";
            }
            else {
                // cout << "<" << line << ",Error>" << endl;
                outputTOKEN << "<" << setw(2) << setfill('0') << line
                            << ",Error>" << endl;
            }
            inputNum = 0;
            type     = -1;
        }

        //对关键词 或 变量进行识别
        if (isLetter(input)) {
            type                      = 2;
            analyzeString[inputNum++] = input;
            input                     = fgetc(file_input);
            while (isLetter(input) || isInteger(input)) {
                analyzeString[inputNum++] = input;
                input                     = fgetc(file_input);
            }
            analyzeString[inputNum++] = '\0';
            inputNum                  = 0;
        }
        if (type == 2) {
            if (isKeyword(analyzeString)) {
                // cout << "<" << line << "," << setw(2) << setfill('0')
                //      << toKeyword(analyzeString) << "," << analyzeString <<
                //      ">"
                //      << endl;
                outputTOKEN << "<" << setw(2) << setfill('0') << line << ","
                            << setw(2) << setfill('0')
                            << toKeyword(analyzeString) << "," << analyzeString
                            << ">" << endl;
                outputLexicalOutput << key2out(toKeyword(analyzeString));
            }
            else {
                string temp = analyzeString;
                if (dfa.isDfa(temp)) {
                    // cout << "<" << line << ",18," << analyzeString << ">"
                    //      << endl;
                    outputTOKEN << "<" << setw(2) << setfill('0') << line
                                << ",18," << analyzeString << ">" << endl;
                    outputLexicalOutput << "z";
                }
                else {
                    // cout << "<" << line << ",Error>" << endl;
                    outputTOKEN << "<" << setw(2) << setfill('0') << line
                                << ",Error>" << endl;
                }
            }
        }

        //对特殊变量进行识别
        if (input == '_') {
            analyzeString[inputNum++] = input;
            input                     = fgetc(file_input);
            while (isLetter(input) || isInteger(input) || input == '_') {
                analyzeString[inputNum++] = input;
                input                     = fgetc(file_input);
            }
            analyzeString[inputNum++] = '\0';
            type                      = 3;
        }
        if (type == 3) {
            string temp = analyzeString;
            if (dfa.isDfa(temp)) {
                // cout << "<" << line << ",18," << analyzeString << ">" <<
                // endl;
                outputTOKEN << "<" << setw(2) << setfill('0') << line << ",18,"
                            << analyzeString << ">" << endl;
                outputLexicalOutput << "z";
            }
            else {
                // cout << "<" << line << ",Error>" << endl;
                outputTOKEN << "<" << setw(2) << setfill('0') << line
                            << ",Error>" << endl;
            }
        }

        //识别 界符
        if (isDelimiter(input)) {
            // cout << "<" << line << ",20," << input << ">" << endl;
            outputTOKEN << "<" << setw(2) << setfill('0') << line << ",20,"
                        << input << ">" << endl;
            outputLexicalOutput << input;

            if ((input = fgetc(file_input)) == EOF) {
                analyzeFinish = true;
                break;
            }
        }

        if (input == '"') {
            analyzeString[inputNum++] = input;
            type                      = 5;
            input                     = fgetc(file_input);
            while (isLetter(input) || isInteger(input) || input == '.' ||
                   input == '+' || input == ' ' || input == '"') {
                analyzeString[inputNum++] = input;
                input                     = fgetc(file_input);
            }

            // cout << analyzeString << endl;
            //对 string 类型 字符串进行识别
            analyzeString[inputNum++] = '\0';
            inputNum                  = 0;
        }

        //对type为 5 进行处理
        if (type == 5) {
            //使用 dfa 对 常量做识别
            string temp = analyzeString;
            if (dfa.isDfa(temp)) {
                // cout << "<" << setw(2) << setfill('0') << line << ",19,"
                //     << analyzeString << ">" << endl;
                outputTOKEN << "<" << setw(2) << setfill('0') << line << ",19,"
                            << analyzeString << ">" << endl;
                outputLexicalOutput << "y";
            }
            else {
                // cout << "<" << setw(2) << setfill('0') << line << ",Error>"
                //     << endl;
                outputTOKEN << "<" << setw(2) << setfill('0') << line
                            << ",Error>" << endl;
            }
            inputNum = 0;
            type     = -1;
        }

        if (input == '\'') {
            analyzeString[inputNum++] = input;
            type                      = 6;
            input                     = fgetc(file_input);
            while (isLetter(input) || isInteger(input) || input == '.' ||
                   input == '+' || input == ' ' || input == '\'') {
                analyzeString[inputNum++] = input;
                input                     = fgetc(file_input);
            }

            // cout << analyzeString << endl;
            //对 string 类型 字符串进行识别
            analyzeString[inputNum++] = '\0';
            inputNum                  = 0;
        }

        //对type为 5 进行处理
        if (type == 6) {
            //使用 dfa 对 常量做识别
            string temp = analyzeString;
            if (dfa.isDfa(temp)) {
                // cout << "<" << line << ",19," << analyzeString << ">" <<
                // endl;
                outputTOKEN << "<" << setw(2) << setfill('0') << line << ",19,"
                            << analyzeString << ">" << endl;
                outputLexicalOutput << "y";
            }
            else {
                // cout << "<" << line << ",Error>" << endl;
                outputTOKEN << "<" << setw(2) << setfill('0') << line
                            << ",Error>" << endl;
            }
            inputNum = 0;
            type     = -1;
        }

        //识别单双目运算符
        if (isSingleOperator(input)) {
            analyzeString[inputNum++] = input;
            if ((input = fgetc(file_input)) == EOF) {
                analyzeFinish = true;
            }
            analyzeString[inputNum++] = input;
            //添加 char 字符串终止符
            analyzeString[inputNum] = '\0';
            if (analyzeFinish == false && isDoubleOperator(analyzeString)) {
                // cout << "<" << line << ",22," << analyzeString << ">" <<
                // endl;
                outputTOKEN << "<" << setw(2) << setfill('0') << line << ",22,"
                            << analyzeString << ">" << endl;
                outputLexicalOutput << analyzeString;

                input = fgetc(file_input);
            }
            else {
                if (analyzeString[0] == '-') {
                    //识别 - 的常数
                    if (isInteger(analyzeString[1])) {
                        inputNum = 2;
                        type     = 4;
                        input    = fgetc(file_input);

                        while (isLetter(input) || isInteger(input) ||
                               input == '.' || input == '+' || input == 'i') {
                            analyzeString[inputNum++] = input;
                            input                     = fgetc(file_input);
                        }
                        analyzeString[inputNum++] = '\0';
                        inputNum                  = 0;
                    }
                    //对type为 4 进行处理
                    if (type == 4) {
                        //使用 dfa 对 常量做识别
                        string temp = analyzeString;
                        if (dfa.isDfa(temp)) {
                            // cout << "<" << line << ",19," << analyzeString
                            //     << ">" << endl;
                            outputTOKEN << "<" << setw(2) << setfill('0')
                                        << line << ",19," << analyzeString
                                        << ">" << endl;
                            outputLexicalOutput << "y";
                        }
                        else {
                            // cout << "<" << line << ",Error>" << endl;
                            outputTOKEN << "<" << setw(2) << setfill('0')
                                        << line << ",Error>" << endl;
                        }
                        inputNum = 0;
                        type     = -1;
                    }
                }
                else {
                    // cout << "<" << line << ",21," << analyzeString[0] << ">"
                    //     << endl;
                    outputTOKEN << "<" << setw(2) << setfill('0') << line
                                << ",21," << analyzeString[0] << ">" << endl;
                    outputLexicalOutput << analyzeString[0];
                }
            }
            inputNum = 0;
        }

        //判断是否结束
        if (input == ' ' || input == '\n' || input == '\t') {
            //计算行数
            if (input == '\n') {
                line++;
            }

            if ((input = fgetc(file_input)) == EOF) {
                analyzeFinish = true;
                break;
            }
            continue;
        }
    }
}

/**
 * @description: 将得到的keyword 的返回值 转化为 string
 * @param {type}
 * @return:
 */
string key2out(int i)
{
    if (i == 0) {  // return 0 r
        return "r";
    }
    if (i == 1) {  // for 1 f
        return "f";
    }
    if (i == 2) {  // while 2 w
        return "w";
    }
    if (i == 3) {  // break 3 b
        return "b";
    }
    if (i == 4) {  // continue 4 c
        return "c";
    }
    if (i == 5) {  // if 5 i
        return "i";
    }
    if (i == 6) {  // else 6 e
        return "e";
    }
    if (i == 7) {  // default 7 d
        return "d";
    }
    if (i == 8) {  // unsigned 8 u
        return "u";
    }
    if (i == 9) {  // long 9 g
        return "g";
    }
    if (i == 10) {  // int 10 t
        return "t";
    }
    if (i == 11) {  // float 11 o
        return "o";
    }
    if (i == 12) {  // double 12 d
        return "d";
    }
    if (i == 13) {  // char 13 a
        return "a";
    }
    if (i == 14) {  // bool 14 l
        return "l";
    }
    if (i == 15) {  // void 15 v
        return "v";
    }
    if (i == 16) {  // string 16 s
        return "t";
    }
    return "0";
}

/**
 * @description: 打开文件
 * @param {type}
 * @return:
 */
void fileOpen()
{
    file_input = fopen(SOURCE, "r+");
    outputTOKEN.open(TOKEN);
    outputLexicalOutput.open(LexicalOutput);
}

/**
 * @description: 关闭文件
 * @param {type}
 * @return:
 */
void fileClose()
{
    outputTOKEN.close();
    outputLexicalOutput.close();
    fclose(file_input);
}